ГПОУ ТО "ДКИТ"

Примеры реализации программ

Задание 1. Тип эксперимента: пакет.

Размер пакета: 32-512 байт.

Тайм-аут: 5 мс.

Вид соединения: дейтаграмма.

Размер передаваемых данных: 8 Кбайт.

Вывод статистики на сервере. Необходимо построить гистограмму, отображающую зависимость времени передачи от размера пакета.

Листинг программы. Реализация на языке C#

Модуль «Клиент»

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Fonns;

using System.Net;

using System.Net.Sockets;

using System.Threading;

using System.Diagnostics;

using System.Runtime.InteropServices;

namespace SIT

{ public partial class Fonnl : Form

{

private int localPort; 11 локальный порт

private int remotePort; // удаленный порт

private int timeOut; II тайм-аут

private long size_data; 11 размер передаваемых данных

IPAddress remotelPAddres; // удаленный IP- адрес public int[] sizes = II массив размеров отправляемых пакетов

new int[] { 32, 64, 128, 256, 512 };

public int s = 0; II переменная для вывода на экран размера отправленного пакета

private delegate void InvokeDelegate(); // делегат, для вывода информации

private AutoResetEvent autoEvent = new AutoResetEvent(false); // события для синхронизации потоков

private AutoResetEvent autoEvent2 = new AutoResetEvent(false);

void PrintLabelStart()

{

label2.Text = "подключение";

}

void PrintLabelConnect()

{

label2.Text = "подключено";

}

void PrintConnectionO

{

richTextBoxl.Text += DateTime.Now + " Подключение к серверуп";

}

void PrintConnectionEnd()

{

richTextBoxl.Text += DateTime.Now + " Соединение установленноп";

richTextBoxl.SelectionStart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();

}

void PrintRequest()

{

richTextBoxl.Text += DateTime.Now + " Отправлен запросп"; richTextBoxl. Selections tart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();

}

void PrintPackedO

{

richTextBoxl.Text += DateTime.Now + " Отправлен пакет размером " + s + " байтп";

richTextBoxl. Selections tart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();

}

void PrintAnsver()

{

richTextBoxl.Text += DateTime.Now + " Получен ответп"; richTextBoxl. Selections tart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();

}

void PrintEnd()

{

richTextBoxl.Text += DateTime.Now + " Отправка данных завер-

шенап";

richTextBoxl. Selections tart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();

}

void EnableButtonO

{

button2.Enabled = true;

}

private void Recive()

{

try

{

UdpClient Recive = new UdpClient(localPort);

IPEndPoint reciver = null;

Red ve.Recei ve(ref rec i ver);

Recive.Close();

autoEvent.SetO;

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

private void ReciveData()

{

try

{

UdpClient Recive = new UdpClient(localPort);

IPEndPoint reciver = null; while (true)

{

Reci ve.Recei ve(ref reciver); autoEvent2.Set();

}

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

private void Request()

{

try

{

label2.BeginInvoke(new InvokeDelegate(PrintLabelStart)); richTextBox 1 .BeginInvoke(new InvokeDelegate(PrintConnection));

UdpClient Send = new UdpClient();

IPEndPoint sender = new IPEndPoint(remoteIPAddres, remotePort);

Thread tRec = new Thread (Red ve); tRec.IsBackground = true; tRec.Start();

string welcome = localPort.ToStringO + + textBox4.Text;

byte[] data = Encoding.UTF8.GetBytes(welcome);

while (true)

{

Send.Send(data, data.Length, sender);

richTextBoxl.BeginInvoke(new InvokeDelegate(PrintRequest)); if (autoEvent.WaitOne(lOOO) = true)

{

richTextBox 1 .BeginInvoke(new InvokeDele- gate(PrintAnsver));

break;

}

}

Send.Close();

label2.BeginInvoke(new InvokeDelegate(PrintLabelConnect)); richTextBox 1 .BeginInvoke(new InvokeDele- gate (Pri ntConnectionEnd));

button2.BeginInvoke(new InvokeDelegate(EnableButton));

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

private void SendData()

{

try

{

UdpClient Send = new UdpClient();

IPEndPoint sender = new IPEndPoint(remoteIPAddres, remotePort);

int index = 0; s = sizes[index]; long tempSize = 0;

Thread tRec2 = new Thread(ReciveData); tRec2.IsBackground = true; tRec2.Start(); while (true)

{

byte[] Data = new byte[sizes[index]];

Send.Send(Data, Data.Length, sender);

richTextBoxl.BeginInvoke(new InvokeDelegate(PrintPacked)); if (autoEvent2.WaitOne(timeOut) = true)

{

tempSize += sizes[index]; richTextBox 1 .BeginInvoke(new InvokeDele- gate(Pri ntAnsver));

autoEvent2 .Reset();

Thread.Sleep(50);

}

if (tempSize = size_data)

{

if (index < (sizes.Length - 1))

{

index++; s = sizes [index]; tempSize = 0;

}

else

break;

tempSize = 0;

}

}

byte[] data = Encoding.UTF8.GetBytes("end"); Send.Send(data, data.Length, sender);

Send.CloseO;

richTextBox 1 .BeginInvoke(new InvokeDelegate(PrintEnd));

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

public Forml()

{

In i ti al i zeComponent(); try {

// Получение имени компьютера.

String host = System.Net.Dns.GetHostNameO;

// Получение ip-адреса.

System.Net.IPAddress ip = Sys- tem.Net.Dns.GetHostByName(host).AddressList[0]; this.textBox4.Text = ip.ToStringO;

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

private void button l_Click(object sender, EventArgs e)

{

try

{

localPort = int.Parse(textBoxl.Text); remotePort = int.Parse(textBox2.Text); timeOut = int.Parse(textBox5.Text);

remotelPAddres = IPAddress.Parse(textBox3.Text); size_data = int.Parse(textBox6.Text);

Thread tRec = new Thread(Request); tRec.IsBackground = true; tRec.Start();

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

private void button2_Click(object sender, EventArgs e)

{

try

{

Thread tRec = new Thread(SendData); tRec.IsBackground = true; tRec.Start();

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

}

}

Модуль «Сервер»

using System;

using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;

using System.Threading;

using System.Diagnostics;

namespace SIT2

{

public partial class Forml : Form

{

private int localPort; // локальный порт

private int remotePort; // удаленный порт

IPAddress remotelPAddres; // удаленный IP-адрес int size; // размер принятого пакета

private AutoResetEvent autoEvent = new AutoResetEvent(false); private delegate void InvokeDelegate(); // делегат, для вывода информации

private int[] sizes = // массив размеров отправляемых пакетов

new int[] { 32, 64, 128, 256, 512 };

private double[] times = new double[]{0, 0, 0, 0, 0}; // массив времен private Stopwatch sWatch = new Stopwatch(); // таймер

void PrintConnectClientO

{

richTextBoxl.Text += DateTime.Now + " Подключен клиент - " + remotelPAddres.ToStringO + " ";

richTextBoxl. Selections tart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();

}

void PrintData()

{

richTextBoxl.Text += DateTime.Now + " Получен пакет данных размером " + size + " байтп";

richTextBox l.SelectionStart = richTextBoxl.Text.Length;

richTextBox 1 .ScrollToCaret();

}

void PrintEnd()

{

richTextBox 1.Text += DateTime.Now + " Передача данных завершена^";

richTextBox l.SelectionStart = richTextBox l.Text.Length; richTextBox 1 .ScrollToCaret();

}

void PrintChartO

{

chartl.Series["Seriesl"].Points.DataBindXY(sizes, times);

}

public Forml()

{

InitializeComponentO;

try

{

// Получение имени компьютера.

String host = System.Net.Dns.GetHostName();

// Получение ip-адреса.

System.Net.IPAddress ip = System.Net.Dns.GetHostByName(host). AddressList[0];

this.textBox2.Text = ip.ToStringO;

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

void Connect()

{

try

{

UdpClient receivingUdpClient = new UdpClient(localPort);

IPEndPoint RemotelpEndPoint = null;

byte[] data = receivingUdpClient.Receive(ref RemotelpEndPoint);

string infoClient = Encoding.UTF8.GetString(data); string port = ip = bool flag = false;

for (int i = 0; i < infoClient.Length; ++i)

{

if (infoClient[i] == '*')

{

flag = true; continue;

}

if (!flag)

port += infoClient[i]; else

ip += infoClient [i];

}

remotePort = int.Parse(port); remotelPAddres = IPAddress.Parse(ip);

UdpClient send = new UdpClient();

IPEndPoint sendering = new IPEndPoint(remoteIPAddres, remote-

Port);

byte[] datagram = new byte[8]; send.Send(datagram, datagram.Length, sendering);

receivingUdpClient.Close();

send.Close();

autoEvent.Set();

richTextBox 1 .BeginInvoke(new InvokeDelegate (PrintConnectClient));

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

void RecivingO

{

try

{

autoEvent.WaitOne();

UdpClient receivingUdpClient = new UdpClient(localPort); IPEndPoint RemotelpEndPoint = null;

UdpClient send = new UdpClient();

IPEndPoint sendering = new IPEndPoint(remoteIPAddres, remote-

Port);

while (true)

{

sWatch.StartO;

byte[] data = receivingUdpClient.Receive(ref RemotelpEndPoint);

sWatch.StopO;

string tempEnd = Encoding.UTF8.GetString(data); if (tempEnd == "end") break; size = data.Length;

richTextBoxl.BeginInvoke(new InvokeDelegate(PrintData)); byte[] datagram = new byte[8]; send.Send(datagram, datagram.Length, sendering);

switch (data.Length)

{

case 32:

times[0] += (double)sWatch.ElapsedMilliseconds / 1000; break; case 64:

times[l] += (double)sWatch.ElapsedMilliseconds / 1000; break;

case 128:

times[2] += (double)sWatch.ElapsedMilliseconds / 1000; break; case 256:

times[3] += (double)sWatch.ElapsedMilliseconds / 1000; break; case 512:

times[4] += (double)sWatch.ElapsedMilliseconds / 1000; break;

};

sWatch.Reset();

}

receivingUdpClient.Close();

send.Close();

richTextBox 1 .BeginInvoke(new InvokeDelegate(PrintEnd)); chartl .BeginInvoke(new InvokeDelegate(PrintChart));

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

private void button l_Click(object sender, EventArgs e)

{

richTextBox 1.Text += DateTime.Now + " Ожидается подключение клиентап";

try

{

localPort = int.Parse(textBoxl.Text);

Thread tRecQ = new Thread(Connect); tRecQ.IsBackground = true; tRecQ. Start();

Thread tRecR = new Thread(Reciving); tRecR.IsBackground = true;

tRecR.Start();

}

catch(Exception ex)

{

MessageBox.Show(ex.ToStringO);

}

}

}

}

Клиент

Сервер

Задание 2. Объем передаваемых данных. 16 Кбайт. Вид соединения: Дейтаграмма.

Таймаут: 15 мс.

Листинг программы. Реализация на языке C++

#include

#pragma hdrstop #include

#include

#include "Unitl.h"

#pragma package(smart_init)

#pragma resource TfMain *fMain;

TFileStream *inpFile, *outFile;

LANA_ENUM lan_number;

NCB neb;

intWorkingLana=2, nSessions=20, nNames=30, Time0ut=15, count=0, NBNAMENUM=0; int s=0;

char NameString[]="IOmeHT", PriemString[]="CepBep"; float size=0;

int VOLUMES []={ 8, 16, 32, 64, 128, 256, 512}; double TIMES[]={0,0,0,0,0,0,0};

intVolum=8;

intdeltaX=30;

#deflne B_S 512 #define TotalSize 24576 void Priem();

_fastcallTfMain::TfMain(TComponent* Owner)

: TForm(Owner)

{

} boolNbReset(byte 1)

{

memset(&ncb,0,sizeof(ncb)); ncb.ncb_command=NCBRESET; ncb.ncb_lana_num=l; ncb.ncb_callname[0]=nSessions; neb. ncb_cal lname [2]=nN ames; if(Netbios(&ncb)!=NRC_GOODRET)

{

fMain->Memo->Lines->Add("Reset NCB Error. RetCode: Ox"+IntToStr(ncb.ncb_retcode)); return 0;

}

else return 1;

} void PaintStatistic()

{

int Max=TIMES[0];

for (int r=l; r<7; r++) if(TIMES[r]>Max) Max=TIMES[r]; int y; int x=0;

fMain->Im->Canvas->Brush->Color=clWhite;

fMain->Im->Canvas->Rectangle(0,0,fMain->Im->Width,fMain->Im-

>Height);

for (int r=0; r<7; r++)

{

if (Max != 0) у = fMain->Im->Height - fMain->Im- >Height*TIMES[r]/(Max* 1.5); else у = 0;

fMain->Im->Canvas->Brush->Color=clBlue;

fMain->Im->Canvas->Rectangle(x,y,(x+deltaX),lMain->Im->Height);

fMain->Im->Canvas->Brush->Color=clWhite;

fMain->Im->Canvas->TextOutA(x+3,y-30,IntToStr(VOLUMES[r])+" байт"); fMain->Im->Canvas->TextOutA(x+3,y-15,FloatToStr(TIMES[r])+" сек"); x+=deltaX;

}

}

void_fastcallTfMain::btFileClick(TObject ^Sender)

{

if (OpenDialog->Execute())

{

edFile->Text=OpenDialog->FileName; inpFile = new TFileStream(edFile->Text, fmOpenRead); s=inpFile->Size;

lbFileSize->Caption = IntToStr(s) + " байт";

bt4->Enabled = true;

}

}

void_fastcallTfMain::FormClose(TObject *Sender, TCloseAction&Action)

{

delete inpFile;

}

void_fastcallTfMain::rbOtprClick(TObject ^Sender)

{

edFile->Enabled=l; btFile->Enabled= 1; lbFileSize->Enabled= 1; btRecv->Visible = 0; bt4->Visible = 1;

1ЬЫате->СарЬоп="Имя: Клиент";

}

void_fastcallTfMain::rbPolClick(TObject ^Sender)

{

edFile->Enabled=0; btFi le->Enabled=0; lbFi leS i ze->Enabled=0; bt4->Visible = 0; btRecv->Visible = 1; lbName->Caption="HMH: Сервер";

}

void_fastcallTfMain::btLANAClick(TObject *Sender)

{

Memo->Lines->Add("-----------------------------------------");

if (NbReset(WorkingLana))

{

memset(&ncb,0,sizeof(ncb));

ncb.ncb_command=NCBENUM;

ncb.ncb_buffer=(unsigned char*)&lan_number; ncb.ncb_length=sizeof(lan_number); if(Netbios(&ncb)==NRC_GOODRET)

{

Memo->Lines->Add("LANA Number List:"); for(inti=0; iLines->Add(IntToStr(i+1)+":

["?+IntToS tr(lan_nu mber.lana[i ])+"]");

Memo->Lines->Add("-----------------------------------------");

}

else

{

Memo->Lines->Add("LANA NCB Error. RetCode:

Ox"+IntToS tr(ncb .ncb_re tcode));

}

}

btGetLANA->Enabled= 1; edGetLANA->Enabled=l;

}

void_fastcallTfMain::btRecvClick(TObject *Sender)

{

Priem();

}

char Buffer[B_S]={0}; clock_t Begin=clock(); double Tim=0;

void Priem()

{

if(NbReset(WorkingLana))

{

TimeOut=S trT oInt(fMai n->edTi meOUT->Text); memset(&ncb,0,sizeof(ncb));

ncb.ncb_command=NCBADDNAME;

neb. ncb_lana_num=W orkingLana;

ncb.ncb_rto = TimeOut;

memset(ncb.ncb_name, 0, NCBNAMSZ);

memcpy(ncb.ncb_name, PriemString, lstrlen(PriemString));

fMain->Refresh();

NBNAMENUM=ncb.ncb_num;

if(Netbios(&ncb)==NRC_GOODRET)

{

count=0; while (1)

{

fMain->Refresh();

char Buffer[B_S]={0};

Buffer[B_S]=NULL;

count++;

memset(&neb,0,sizeof(ncb)); ncb.ncb_command=NCBDGREC V; neb. ncb_lana_num=W orkingLana; neb. ncb_num=0xFF; ncb.ncb_buffer=(PUCHAR)Buffer; neb. ncb_length=Vol um;

if(Netbios(&ncb)==NRC_GOODRET)

{

if ( Buffer[l ]=='-' && Buffer[2]=='~' && Buffer[3]=='')

{

fMain->Memo->Lines->Add("Coo6uieHHe было получено"); fMain->Memo->Lines->Add(" "); goto Exit;

}

if ( Buffer[l]=='~' && Buffer[2]==' ’ && Buffer[3]==' ’)

{

Уо1ит*=2;

count=0;

fMain->Memo->Lines->Add("Next: "+IntToStr(Volum)+" байт"); fMain->Memo->Lines->Add(" ");

}

else

{

fMain->Memo->Lines->Add('TIojiy4eHo"); fMain->Memo->Lines->Add(IntToStr(count)+": "+Buffer); fMain->Memo->Lines->Add(" ");

}

}

В uffer[B_S ]=NULL;

} 11 while } I I if Netbios else {

fMain->Memo->Lines->Add("ADDNAME NCB Error. RetCode: Ox"+IntToStr(ncb.ncb_retcode));

fMain->Memo->Lines->Add("-----------------------------------------");

}

} 11 if Reset Exit:

}

inti=0;

//---------------------------------------------------------------------------

void_fastcallTfMain::bt4Click(TObject ^Sender)

{

intSendData=0;

Volum = VOLUMES [i];

lbV->Caption="Packet: "+IntToStr(Volum)+" byte(s)"; fMain->Refresh(); char Buffer[B_S]={ 0}; if (NbReset(WorkingLana))

{

TimeOut=S trToIn t(edTimeOUT->Tex t);

memset(&ncb,0,sizeof(ncb));

ncb.ncb_command=NCBADDNAME;

neb. ncb_lana_n um=W orkingLana; ncb.ncb_rto = TimeOut;

memcpy(&ncb.ncb_name,NameString,lstrlen(NameString));

fMain->Refresh();

ncb.ncb_buffer=(PUCHAR)Buffer;

neb. ncb_length=Vol um;

memcpy(&ncb.ncb_callname,PriemString,lstrlen(PriemString));

Netbios(&ncb);

NBNAMENUM=ncb.ncb_num;

count=0;

Begin=clock();

while(l){

char Buffer[B_S]={0}; count++;

if (count>(s/Volum))

{

if (Volum == B_S)

{

Buffer[B_S]=NULL;

Buffer[ 1 Buffer[2]='~';

Buffer[3]='

neb. ncb_command=NCBDGSEND; ncb.ncb_buffer=(PUCHAR)Buffer; ncb.ncb_length=Volum;//sizeof(Buffer);

Netbios(&ncb);

Memo->Lines->Add("Coo6meHne6bmooToenaHO "); Memo->Lines->Add(" ");

TIMES [i]=Tim;

deltaX=(fMain->Im->Width)/7;

PaintStatistic();

break;

}

else

{

Buffer[B_S]=NULL;

Buffer [1 Buffer[2]=' ’;

Buffer[3]=

ncb.ncb_command=NCBDGSEND;

ncb.ncb_buffer=(PUCHAR)Buffer;

ncb.ncb_length=Volum;

Netbios(&ncb);

Memo->Lines->Add("Next: "+IntToStr(Volum*2)+" byte(s)"); Memo->Lines->Add(" ");

TIMES [i]=Tim; break;

}

}

else

{

Buffer[B_S]=NULL;

inpFile->Seek(Volum*(count-l), soFromBeginning); inpFile->Read(Buffer, Volum);

Memo->Lines->Add(IntToStr(count)+":"+ Buffer); Memo->Lines->Add(" "); neb. ncb_command=NCBDGSEND; ncb.ncb_buffer=(PUCHAR)Buffer; neb. ncb_length=Vol um;

Netbios(&ncb);

SendData+=Volum;

}

Tim=((clock()-Begin)/CLK_TCK);

fMain->Refresh();

} // while(l)

}

else

{

Memo->Lines->Add("OmH6Kanepe;aa4H" );

Memo->Lines->Add(" ");

}

i++;

if (i< 7) fMain->bt4Click(fMain); else {

lbV->Caption="Packet:"; i = 0;

}

}

void_fastcallTfMain::FormCreate(TObject ^Sender)

{

Im->Canvas->Brush->Color=clWhite; Im->Canvas->Rectangle(0,0,Im->Width,Im->Height); rbPol->Checked = 1;

}

void_fastcallTfMain::btGetLANAClick(TObject ^Sender)

{

WorkingLana=StrToInt(edGetLANA->Text);

}

Сервер

Задание 3. Тип эксперемента: time out.

Размер пакета 512 байт.

TimeOut в диапозоне от 15 до 25 мс.

Вид соединения: логический канал.

Размер данных: 32 кбайта.

Вывод статистики: на клиенте.

Листинг программы. Реализация на языке Kotlin с использованием GUUavaFX

ClientMain.kt

import j avafx .appl icati on. Appl ication import javafx.fxml.FXMLLoader import javafx.scene.Parent import javafx.scene.Scene import javafx.stage.Stage class ClientMain : Application() {

@Throws(Exception: :class) ovenide fun start(primaryStage: Stage) { System.setPropertyC'prism.lcdtext", "false") val root = FXMLLoad-

er.load(javaClass.getResource("sample.fxml")) primary Stage, title = "Client" primaryStage.scene = Scene(root, 800.0, 400.0) pri mary S tage. sho w()

}

companion object {

@JvmStatic

fun main(args: Array) { launch(Cl ientMai n: rclass.java)

}

}

}

sample.fxml

_"serv erIpField" promptText="IP Сервера" Grid- Pane.rowIndex=" 1 ">

filelnput. channel .position(O)

println("Данные с задержкой $delay мс между пакетами отправлены")

}

output. write("exit".toByteArray())

output.flushO

button. isDisable = false

while (lisEnd) {

}

} catch (e: Exception) { e.pri ntStackT race() button. isDisable = false }

}

fun bytesToLong(bytes: ByteArray): Long { val buffer = ByteBuffer.allocate(java.lang.Long.BYTES) buffer.put(bytes) buffer.flipO return buffer, long }

}

}

ServerMain.kt

i mport javafx .appli cati on. Appl i cation import javafx.fxml.FXMLLoader import javafx.scene.Parent import javafx.scene.Scene import javafx.stage.Stage import java.io.BufferedReader import java.io.IOException import java.io.InputStreamReader import java.io.PrintWriter import java.net.ServerSocket import java.net.Socket

/**

class ServerMain: Application() { override fun start(primaryStage: Stage) { System.setPropertyO'prism.lcdtext", "false") val root = FXMLLoader.load(javaClass.getResource ("main.fxml"))

primaryStage.title = "Server" primaryStage.scene = Scene(root, 800.0, 400.0) primaryStage.show()

}

companion object {

@JvmStatic

fun main(args: Array) { launch(ServerMain::class.java)

}

}

}

main.fxml

cTextArea fx:id="logArea" editable="false" prefHeight="325.0" pref- Width="800.0" wrapText="true" BorderPane.alignment="CENTER" />

ServerController.kt

import javafx.beans.value.ChangeListener import javafx.fxml.FXML import j avafx. scene .control. В u tton

import javafx .scene.control .Label

import javafx.scene.control.TextArea

import java.net.Networklnterface

import java.net.ServerSocket

import java.net.Socket

import java.util.regex.Pattern

import javafx.beans.value.ObservableValue

import java.io.*

import java.nio.ByteBuffer

class ServerController {

private val SOCKET_NUMBER = 9999

private val PACKET_SIZE = 512

@FXML

lateinit var refreshButton: Button @FXML

lateinit var rebootButton: Button @FXML

lateinit var currentlpLabel: Label @FXML

lateinit var logArea: TextArea val threadRunnable: Runnable = Runnable { logArea.appendText("CepBep запущенп") var out: OutputStream? = null var servers: ServerSocket? = null var fromclient: Socket? = null javafx.application.Platform.runLater { rebootButton.isDisable = true rebootButton.text = "Сервер запущен"

}

try {

servers = ServerSocket(SOCKET_NUMBER) } catch (e: IOException) { logArea.appendTextCНевозможно прослушать порт " + SOCKET_NUMBER + "п")

}

try {

log Area.appendText( "Ожидание подключения клиента. An") fromclient = servers! !.accept()

logArea.appendText( "Клиент " + fromclient.inetAddress.hostAddress + подключилсяп")

} catch (e: IOException) {

logArea.appendText("HeB03MO>KHO подключить клиентап")

}

var "in4 = fromclient! !.getInputStream()

var buffer = ByteArray(PACKET_SIZE)

out = fromclient.getOutputStreamO

var now = System.currentTimeMillis()

var input = 'in'.read(buffer)

now = System.cunentTimeMillisO - now

var totalTime = OL

var time = now

val output: String

var past: String? = null

while ((input) != null) {

var str = String(buffer)

if (str.contains("exit")ll past == str) {

break

} else if (str.contains("Onext")) { out.write(longToBytes(time - now)) out.flushO

println("Данные обработаны за ${time - now} мс") str = " Данные обработаны за ${time - now} мспп" totalTime+=time time = 0 } else {

out.write(longToBytes(-2L))

out.flushO

// println("Пакет обработан за $now мс") str += 'ЛпПакет обработан за $now мсп"

}

javafx.application.Platform.runLater { logArea.appendText(str)

}

past = str

now = System.currentTimeMillis() input = 'in'.read(buffer) now = System.cuiTentTimeMillis() - now time += now }

out.write(longToBytes(-lL))

out.flushO

javafx.application.Platfomi.runLater { rebootButton.isDi sable = false rebootButton.text = "Перезапустить сервер"

}

out.closeO

vin'.close()

fromclient.closeO

servers?.close()

javafx.application.Platfomi.runLater {

logArea.appendText("06utee время обработки пакетов StotalTime

мсп")

}

}

fun initializeO {

currentlpLabel.text = "Текущий IP адрес: " + getCurrentIp() refreshButton.setOnAction {

currentlpLabel.text = "Текущий IP адрес: " + getCurrentlpO

}

logArea.textPropertyO.addListener { observable, oldValue, newValue -> logArea.scrollTop = java.lang.Double.MAX_VALUE //this will scroll to the bottom

//use Double.MIN_VALUE to scroll to the top

}

rebootButton.setOnAction { logArea.text ="" startReceive()

}

startReceive()

}

private fun staitReceive(){

Thread(threadRunnable).stai1()

}

private fun getCurrentIp(): String {

val networklnterfaces = Networklnterface.getNetworklnterfacesO

while (networklnterfaces.hasMoreElementsO) {

val networklnterface = networkInterfaces.nextElement()

val addresses = networklnterface.inetAddresses

while (addresses.hasMoreElements()) {

val address = addresses.nextElement()

if (address.hostAddress != "I27.0.l.l"&& address.hostAddress != "127.0.0.1"

&& isIpAddress(address.hostAddress)) { return address.hostAddress }

}

}

return "Устройство не подключено"

}

fun isIpAddress(address: String): Boolean {

val pattern = Pattem.compile("A(([0-9]l[l-9][0-9]ll[0-9]{2}l2[0-4][0- 9] I25 [0-5]).) {3} ([0-9] I [ l-9] [0-9] 11 [0-9] {2} I2 [0-4] [0-9] I25 [0-5])$") return pattem.matcher(address).matches()

}

fun longToBytes(x: Long): ByteArray { val buffer = ByteBuffer.allocate(java.lang.Long.BYTES) buffer.putLong(x) return buffer.arrayO }

fun bytesToLong(bytes: ByteArray): Long { val buffer = ByteBuffer.allocate(java.lang.Long.BYTES) buffer.put(bytes) buffer.flipO return buffer.long }

Пожелании программистам

Чтобы освоить программирование приложений на выше рассмотренных протоколах, необходимо иметь опыт программирования не меньше 1 года, а чтобы правильно уметь ими пользоваться - как минимум 2-3 года. Для начинающих программистов достаточно изучить основные типы библиотеки VCL (хотя некоторые классы в ней не продуманны и не согласованы). Функциональность и замудренность сетевых классов оставляет желать лучшего, а полезны только классы TIdTCPServer, TIdClient, TIdUDPServer и TldUDPClient. Все остальные сетевые классы нужны, наверное, только самим разработчикам этой библиотеки.

Внимание!!! При сдаче лабораторных работ ЗАПРЕЩЕНО использовать библиотеку нестандартных типов AltemativeTypes, так как она содержит сетевые классы с автоматическим управлением каналами и протоколами, а значит, нет смысла изучать устройство сокетов. Разрешается только ознакомиться со всеми возможностями этих сетевых протоколов и изучить их свойства. Также запрещено использование в частных и коммерческих целях без уведомления автора.

В данном пособии рассмотрено 30 % материала по управлению этими протоколами, другие 30 % вы узнаете из лабораторных, а 40 % информации вы уже должны знать, иначе нет смысла даже пытаться программировать с нуля.

САМОЕ ГЛАВНОЕ для программиста - это красивый почерк в его программном коде.

Для решения задач, связанных с написанием программ для организации обмена данными с сети с использованием сетевых протоколов, в качестве эффективного инструментального средства можно воспользоваться модулем Alternative Types Library.